package logging;

import java.util.ArrayList;
import java.util.Map;

import Exception.CustomNotImplementsICustom;
import Exception.NonExistingConstructorException;
import Filter.Filter;
import Handler.ConsoleHandler;
import Handler.CustomHandler;
import Handler.FileHandler;
import Handler.Handler;

public class HandlerMaker {

	loggerConfig config;
	ArrayList<Handler> handlers;
	
	public HandlerMaker(loggerConfig config) {
		this.config = config;
		this.handlers = new ArrayList<Handler>();
	}
	
	/*
	 * creates handlers form configuration
	 * return handlers
	 */
	public ArrayList<Handler> createHandler(){
		createFileHandler();
		createConsoleHandler();
		try {
			createCustomHandler();
		} catch (ClassNotFoundException | NoSuchMethodException
				| SecurityException | NonExistingConstructorException
				| CustomNotImplementsICustom e) {
			e.printStackTrace();
		}
		return handlers;
	}
	
	/*
	 * creates files handlers from configuration
	 */
	private void createFileHandler(){
		if ((config != null) && (!config.getMapFiles().isEmpty())){
			for (Map.Entry<String, Filter> values : config.getMapFiles().entrySet()){
				FileHandler fileHandler = new FileHandler(values.getKey());
				if (values.getValue() != null)
					fileHandler.addFilter(values.getValue());
				handlers.add(fileHandler);
			}
		}
	}
	
	/*
	 * if console is enabled create console handler form configuration
	 */
	private void createConsoleHandler(){
		if ((config != null) && (config.enableConsole())){
			Handler consoleHandler = new ConsoleHandler();
			if (config.getFilterConsole() != null)
				consoleHandler.addFilter(config.getFilterConsole());
			handlers.add(consoleHandler);
		}
	}
	
	private void createCustomHandler() throws ClassNotFoundException, NoSuchMethodException, SecurityException, NonExistingConstructorException, CustomNotImplementsICustom{
		if ((config != null) && (!config.getMapDestination().isEmpty())){
			for (Map.Entry<String, ArrayList<String>> values : config.getMapDestination().entrySet()){
				if (values.getValue() != null){
					Object[] arg = null;
					if (!values.getValue().isEmpty()){
						arg = new Object[values.getValue().size()];
						for (int i = 0; i < values.getValue().size(); i++)
							arg[i] = values.getValue().get(i);
					}else{
						arg = new Object[0];
					}
					CustomHandler custom = new CustomHandler(values.getKey().trim(), new Object[0]);
					Filter filterForCustom = this.getFilterForCustomHandler(values.getKey());
					if (filterForCustom != null)
						custom.addFilter(filterForCustom);
					handlers.add(custom);
				}
			}
			
		}
	}
	
	private Filter getFilterForCustomHandler(String custom){
		if ((config != null) && (!config.getMapFiles().isEmpty())){
			for (Map.Entry<String, Filter> values : config.getMapFiles().entrySet()){
				if (values.getKey().equals(custom)){
					return values.getValue();
				}
			}
		}	
		return null;
	}
	
	public static Handler createHandler(String name){
		if (name.equals("console"))
			return new ConsoleHandler();
		return new FileHandler(name);
	}
}
